package cn.base.web.lock;

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
@ConditionalOnProperty(name = "redis.enabled", havingValue = "true",matchIfMissing=true)
@Primary
public class RedissionLock implements LockService{
    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private LockProperties lockProperties;
    @Override
    public <T> T lock(String key, Callable<T> valueLoader) throws Exception {
        T t=null;
        RLock lock=redissonClient.getLock(key);
        try {
            boolean locked=lock.tryLock(lockProperties.getAcquireTimeout().getSeconds(),lockProperties.getLeaseTime().getSeconds(),TimeUnit.SECONDS);
            if(locked){
                t=valueLoader.call();
            }else{
                log.warn("tryLock false");
            }
        }catch(InterruptedException e1){
            return null;
        }catch(Exception e) {
            throw e;
        } finally {
            lock.unlock();
        }
        return t;
    }
}
